# -*- encoding: utf-8 -*-

"""
@File:      tc_lmdb_lmdb_func_002.py
@Time:      2024/03/27 14:33:20
@Author:    chenchunhu
@Version:   1.0
@Contact:   wb-cch358909@alibaba-inc.com
@License:   Mulan PSL v2
@Modify:    chenchunhu
"""

from common.basetest import LocalTest

class Test(LocalTest):
    """
    See tc_lmdb_lmdb_func_002.yaml for details

    :avocado: tags=P2,noarch,local,fix
    """

    PARAM_DIC = {"pkg_name": "lmdb lmdb-devel gcc"}
    def setUp(self):
        super().setUp(self.PARAM_DIC)
        cmdline = '''cat >lmdb_test3.c<<"EOF"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "lmdb.h"

#define ENV_PATH "./lmdb_test3_db"
#define MAX_SIZE 1024
#define NUM_ITEMS 100

void check(int rc) {
    if (rc != MDB_SUCCESS) {
        fprintf(stderr, "LMDB Error: %s\\n", mdb_strerror(rc));
        exit(EXIT_FAILURE);
    }
}

int main() {
    MDB_env *env;
    MDB_dbi dbi;
    MDB_txn *txn;
    MDB_val key, data;
    int rc;

    // 创建或打开一个LMDB环境
    rc = mdb_env_create(&env);
    check(rc);
    rc = mdb_env_set_mapsize(env, MAX_SIZE * NUM_ITEMS);
    check(rc);
    rc = mdb_env_open(env, ENV_PATH, 0, 0664);
    check(rc);

#if WRITE_TEST
    // 写入阶段
    rc = mdb_txn_begin(env, NULL, 0, &txn); // 使用写标志开始事务
    check(rc);
    rc = mdb_dbi_open(txn, NULL, 0, &dbi);
    check(rc);

    for (int i = 0; i < NUM_ITEMS; ++i) {
        key.mv_size = sizeof(int);
        key.mv_data = &i;
        char value[MAX_SIZE];
        snprintf(value, MAX_SIZE, "Item #%d", i);
        data.mv_size = strlen(value) + 1;
        data.mv_data = value;

        rc = mdb_put(txn, dbi, &key, &data, 0);
        check(rc);
    }

    printf("Data writing completed\\n");

    rc = mdb_txn_commit(txn);  // 提交事务以确保写入持久化
    check(rc);
    mdb_dbi_close(env, dbi);
#else
    // 读取阶段
    rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn); // 使用只读标志开始事务
    check(rc);
    rc = mdb_dbi_open(txn, NULL, 0, &dbi);
    check(rc);

    for (int i = 0; i < NUM_ITEMS; ++i) {
        key.mv_size = sizeof(int);
        key.mv_data = &i;

        rc = mdb_get(txn, dbi, &key, &data);
        check(rc);

        printf("Key: %d, Value: %s\\n", i, (char *)data.mv_data);
        // 简单的完整性校验
        char expected_value[MAX_SIZE];
        snprintf(expected_value, MAX_SIZE, "Item #%d", i);
        assert(strcmp(expected_value, data.mv_data) == 0);
    }

    mdb_txn_abort(txn); // 结束读取事务
    mdb_dbi_close(env, dbi);
#endif
    mdb_env_close(env); // 关闭环境句柄

    return EXIT_SUCCESS;
}
EOF'''
        self.cmd(cmdline)
        self.cmd("mkdir -p lmdb_test3_db")


    def test(self):
        self.cmd("gcc lmdb_test3.c -o lmdb_test3 -DWRITE_TEST=1 -llmdb")
        code, lmdb_result = self.cmd("./lmdb_test3")
        self.assertIn("Data writing completed", lmdb_result)
        self.cmd("gcc lmdb_test3.c -o lmdb_test3 -DWRITE_TEST=0 -llmdb")
        code, lmdb_result = self.cmd("./lmdb_test3")
        self.assertIn("Key: 99, Value: Item #99", lmdb_result)

    def tearDown(self):
        super().tearDown(self.PARAM_DIC)
        self.cmd("rm -rf lmdb_test3.c lmdb_test3 lmdb_test3_db")
